﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NGinnBPM.Lib.Data;
using NGinnBPM.Lib.Interfaces;
using System.Runtime.Serialization;

namespace NGinnBPM.Lib.Schema
{
    /// <summary>
    /// Process package definition.
    /// </summary>
    [Serializable]
    [DataContract]
    public class PackageDefinition
    {
        public static readonly string PACKAGE_NAMESPACE = "http://www.nginn.org/PackageDefinition.1_0";
        
        public PackageDefinition()
        {
            PackageTypes = new List<TypeSet>();
            ProcessDefinitionNames = new List<string>();
            ProcessDefinitions = new List<ProcessDefinition>();
            Aliases = new Dictionary<string, string>();
        }

        [DataMember]
        public string Name { get; set; }

        [DataMember]
        public List<TypeSet> PackageTypes { get; set; }

        [DataMember]
        public List<string> ProcessDefinitionNames { get; set; }

        [DataMember(IsRequired=false, EmitDefaultValue=false)]
        public Dictionary<string, string> Aliases { get; set; }

        [IgnoreDataMember]
        public List<ProcessDefinition> ProcessDefinitions { get; set; }
        /*
        public ProcessDefinition GetProcessDefinition(string name)
        {
            string nm = name;
            if (_aliases.ContainsKey(name))
                nm = _aliases[name];

            if (_processes.ContainsKey(nm))
            {
                return _processes[nm];
            }
            if (PackageStore != null)
            {
                ProcessDefinition pd = PackageStore.GetProcessDefinition(nm);
                if (pd != null)
                {
                    _processes[pd.LocalName] = pd;
                    if (!_processNames.Contains(pd.LocalName))
                        _processNames.Add(pd.LocalName);
                }
                return pd;
            }
            return null;
        }

        public void AddProcessDefinition(ProcessDefinition pd)
        {
            ProcessDefinition pd2 = GetProcessDefinition(pd.LocalName);
            if (pd2 != null)
                throw new Exception("Process already defined: " + pd.LocalName);
            if (!_processNames.Contains(pd.LocalName))
                _processNames.Add(pd.LocalName);
            pd.Package = this;
            _processes[pd.LocalName] = pd;
        }*/

        public void SetAlias(string processName, string alias)
        {
            if (Aliases == null)
                Aliases = new Dictionary<string, string>();
            Aliases.Remove(alias);
            Aliases.Add(alias, processName);
        }


        public static string GetPackageName(string definitionId)
        {
            string[] s = definitionId.Split('.');
            if (s.Length > 3 || s.Length <= 1) throw new Exception();
            return s[0];
        }

        public static bool SplitDefinitionId(string defId, out string package, out string processName, out string version)
        {
            package = processName = version = null;
            string[] s = defId.Split('.');
            if (s.Length > 3 || s.Length == 0) return false;
            if (s.Length == 1)
            {
                processName = s[0];
            }
            else
            {
                package = s[0];
                processName = s[1];
                version = s.Length == 3 ? s[2] : null;
            }
            return true;
        }
    }
}
